home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / cgazv4n3.zip / COMPRESS.ASM < prev    next >
Assembly Source File  |  1990-02-07  |  14KB  |  372 lines

  1.         PAGE 60,132
  2. ; -------------------  COMPRESS.ASM ---  LISTING 1  -----------------
  3. ; Contains the 2 functions, Pack3 and UnPack3.
  4. ;
  5. ; Assembler: Microsoft Assembler (MASM) or Turbo Assembler (TASM)
  6. ; Memory model: any
  7. ;
  8. ;    To assemble :    MASM compress /ML /dMSIZE=?;
  9. ;                  or TASM compress /ML /dTASM /dMSIZE=?;
  10. ;
  11. ;       where    MSIZE = 1   Small Memory Model     code<64k  data<64k
  12. ;                      = 2   Medium Memory Model    code>64k  data<64k
  13. ;                      = 3   Compact Memory Model   code<64k  data>64k
  14. ;                      = 4   Large Memory Model     code>64k  data>64k
  15. ;
  16. ; Author : Bob Zigon
  17. ; Date   : June 9, 1988
  18. ; -------------------------------------------------------------------
  19.  
  20.         DOSSEG
  21.  
  22. IFNDEF MSIZE
  23.    %OUT ***
  24.    %OUT *** ERROR : Must specify MSIZE param for Memory Model Selection
  25.    %OUT ***
  26. ELSE
  27.    IF MSIZE LT 1 OR MSIZE GT 4
  28.       %OUT ***
  29.       %OUT *** ERROR : MSIZE Range 1 - 4
  30.       %OUT ***
  31.    ENDIF
  32.    IF MSIZE EQ 1
  33.       IFNDEF TASM
  34.          .model small,c
  35.       ELSE
  36.          .model small
  37.       ENDIF
  38.       %OUT *** Memory Model : SMALL
  39.    ENDIF
  40.    IF MSIZE EQ 2
  41.       IFNDEF TASM
  42.          .model medium,c
  43.       ELSE
  44.          .model medium
  45.       ENDIF
  46.       %OUT *** Memory Model : MEDIUM
  47.    ENDIF
  48.    IF MSIZE EQ 3
  49.       IFNDEF TASM
  50.          .model compact,c
  51.       ELSE
  52.          .model compact
  53.       ENDIF
  54.       %OUT *** Memory Model : COMPACT
  55.    ENDIF
  56.    IF MSIZE EQ 4
  57.       IFNDEF TASM
  58.          .model large,c
  59.       ELSE
  60.          .model large
  61.       ENDIF
  62.       %OUT *** Memory Model : LARGE
  63.    ENDIF
  64. ENDIF
  65.  
  66.         .data
  67.         include COMPRESS.TBL  ; see example 
  68.  
  69.         .code
  70.  
  71. ; -------------------------------------------------------------------
  72. ; PACK3 -- this routine will compress a string of characters into exactly
  73. ;           2/3 the space according to the translation tables built by
  74. ;           BUILD.C.
  75. ;
  76. ;           The algorithm is based on the following polynomial.
  77. ;
  78. ;           P(C1, C2, C3) = C3*40**2 + C2*40**1 + C1*40**0
  79. ;
  80. ;
  81. ; C Prototype :
  82. ;
  83. ;        short int Pack3(char *InpBuf, short int NumChar, char *OutBuf)
  84. ;
  85. ;
  86. ; Input  : InpBuf  -- Ptr to the Input Buffer.
  87. ;          NumChar -- Number of characters to Pack (Must be > 0).
  88. ;          OutBuf  -- Ptr to Output Buffer.
  89. ;
  90. ; Return : Number of words in the packed string.
  91. ; -------------------------------------------------------------------
  92.  
  93. IFNDEF TASM                     ; MASM prologue
  94. Pack3 PROC USES SI DI, InpBuf:PTR, NumChar:WORD, OutBuf:PTR
  95.       LOCAL NumXlate:WORD
  96.  
  97. ELSE                            ; TASM prologue
  98.       public _Pack3
  99. _Pack3 PROC
  100.       ARG InpBuf:PTR,NumChar:WORD,OutBuf:PTR
  101.       LOCAL NumXlate:WORD=AutoSize
  102.       push bp
  103.       mov bp,sp
  104.       sub sp,AutoSize             ; Allocate some local variables
  105.       push si
  106.       push di                     ; Save in case Register Variables = ON
  107. ENDIF
  108.  
  109.       xor ax,ax
  110.       mov NumXlate,ax             ; Zero out NumXlate
  111.  
  112.  IF MSIZE EQ 3 OR MSIZE EQ 4      ; 32 bit pointers
  113.       les si,InpBuf
  114.       mov cx,es                   ; Save Source String segment
  115.  
  116. p10:     mov es,cx                ; ES is segment of Source String
  117.          mov al,es:[si]           ; Get a character from the source string
  118.          inc si                   ; Inc offset portion of pointer
  119.          shl ax,1                 ; Times 2 for word addressing
  120.          mov bx,ax
  121.          lea bx,Xlate0[bx]        ; BX points to the term to sum into DX
  122.  
  123.          mov dx, [bx]             ; DX will accumulate the polynomial
  124.          dec WORD PTR NumChar     ; 1 less character to consider
  125.          jz p100                  ; Exit when no more characters to translate
  126.  
  127.          mov al,es:[si]           ; Get a character from the source string
  128.          inc si
  129.          shl ax,1                 ; Times 2 for word addressing
  130.          mov bx,ax
  131.          lea bx,Xlate1[bx]        ; BX points to the term to sum into DX
  132.          add dx, [bx]             ; Add in the next term
  133.          dec WORD PTR NumChar     ; 1 less character to consider
  134.          jz p100                  ; Exit when no more characters to translate
  135.  
  136.          mov al,es:[si]           ; Get a character from the source string
  137.          inc si
  138.          shl ax,1                 ; Times 2 for word addressing
  139.          mov bx,ax
  140.          lea bx,Xlate2[bx]        ; BX points to the term to sum into DX
  141.          add dx, [bx]             ; Add in the last term
  142.          les di,OutBuf
  143.          mov es:[di],dx           ; Save the result to the Output buffer
  144.          inc WORD PTR [OutBuf]    ; Increment twice
  145.          inc WORD PTR [OutBuf]
  146.          inc WORD PTR NumXlate
  147.          dec WORD PTR NumChar     ; 1 less character to consider
  148.          jz p110                  ; Exit when no more characters to translate
  149.       jmp short p10
  150.  
  151. p100: les di,OutBuf
  152.       mov es:[di],dx
  153.       inc WORD PTR NumXlate
  154.  
  155. p110: mov ax,NumXlate             ; Return the Number of Words in dest
  156.  ELSE
  157.       mov si,InpBuf               ; SI will point to the input buffer
  158.       mov di,OutBuf               ; DI will point to the output buffer
  159.  
  160.       cld
  161.  
  162. p10:     lodsb                    ; Get a character from the source string
  163.          shl ax,1                 ; Times 2 for word addressing
  164.          mov bx,ax
  165.          lea bx,Xlate0[bx]        ; BX points to the term to sum into DX
  166.  
  167.          mov dx, [bx]             ; DX will accumulate the polynomial
  168.          dec WORD PTR NumChar     ; 1 less character to consider
  169.          jz p100                  ; Exit when no more characters to translate
  170.  
  171.          lodsb                    ; Get a character from the source string
  172.          shl ax,1                 ; Times 2 for word addressing
  173.          mov bx,ax
  174.          lea bx,Xlate1[bx]        ; BX points to the term to sum into DX
  175.          add dx, [bx]             ; Add in the next term
  176.          dec WORD PTR NumChar     ; 1 less character to consider
  177.          jz p100                  ; Exit when no more characters to translate
  178.  
  179.          lodsb                    ; Get a character from the source string
  180.          shl ax,1                 ; Times 2 for word addressing
  181.          mov bx,ax
  182.          lea bx,Xlate2[bx]        ; BX points to the term to sum into DX
  183.          add dx, [bx]             ; Add in the last term
  184.          mov [di],dx              ; Save the result to the Output buffer
  185.          inc di
  186.          inc di                   ; Inc offset twice for word addressing
  187.          inc WORD PTR NumXlate
  188.          dec WORD PTR NumChar     ; 1 less character to consider
  189.          jz p110                  ; Exit when no more characters to translate
  190.       jmp short p10
  191.  
  192. p100: mov [di],dx
  193.       inc WORD PTR NumXlate
  194.  
  195. p110: mov ax,NumXlate             ; Return the Number of Words in dest
  196.  
  197.  ENDIF
  198.  
  199. IFNDEF TASM
  200.       ret                         ; MASM does cleanup automatically
  201. Pack3 endp
  202.  
  203. ELSE                              ; TASM cleanup
  204.       pop di
  205.       pop si
  206.       mov sp,bp                   ; Deallocate the local variables
  207.       pop bp                      ; Reset BP
  208.       ret
  209. _Pack3 endp
  210. ENDIF
  211.  
  212. ; -------------------------------------------------------------------
  213. ; UNPACK3 -- this routine will unpack the string of characters that
  214. ;             were previously packed with PACK3. The length of the
  215. ;             unpacked string will be a multiple of 3. The unpacked
  216. ;             string will also be NULL terminated.
  217. ;
  218. ; C Prototype :
  219. ;
  220. ;        short int UnPack3(char *InpBuf, short int NumWord, char *OutBuf)
  221. ;
  222. ;
  223. ; Input  : InpBuf  -- Ptr to the Input Buffer.
  224. ;          NumWord -- Number of words to UnPack (Must be > 0).
  225. ;          OutBuf  -- Ptr to Output Buffer.
  226. ;
  227. ; Return : Number of characters in the unpacked string.
  228. ; -------------------------------------------------------------------
  229. IFNDEF TASM                     ; MASM prologue
  230. UnPack3 PROC USES DI SI, InpBuf:PTR,NumWord:WORD,OutBuf:PTR
  231.       LOCAL NumConvert:WORD
  232.  
  233. ELSE                            ; TASM prologue
  234.       public _UnPack3
  235. _UnPack3 proc
  236.       arg InpBuf:PTR,NumWord:WORD,OutBuf:PTR
  237.       local NumConvert:word=AutoSize
  238.       push bp
  239.       mov bp,sp
  240.       sub sp,AutoSize             ; Allocate some local variables
  241.       push si
  242.       push di                     ; Save in case Register Variables = ON
  243. ENDIF
  244.  
  245.       xor ax,ax
  246.       mov dx,ax
  247.       mov NumConvert,ax
  248.       mov cx,40                   ; Divisor for extracting character
  249.  
  250.  IF MSIZE EQ 3 OR MSIZE EQ 4      ; 32 bit pointers
  251.  
  252. up10: les di,InpBuf
  253.       mov ax,es:[di]
  254.       inc WORD PTR [InpBuf]
  255.       inc WORD PTR [InpBuf]
  256. ;
  257. ; The following 3 blocks of code are identical. You could very easily
  258. ; loop over the first block 3 times and achieve the same effect. I however
  259. ; feel that speed is more important than memory utilization. As a result,
  260. ; I prefer to 'unwrap' the loop 3 times and produce the inline code, than
  261. ; suffer the penalties associated with flushing the prefetch queue when
  262. ; the necessary jump at the bottom of the loop is executed.
  263. ;
  264.          div cx                   ; DX will get the remainder
  265.          shl dx,1                 ; *2 for word addressing into ToAscii Table
  266.          mov bx,dx
  267.          xor dx,dx                ; Zero out DX for the next division
  268.          lea bx,ToAscii[bx]       ; BX points into the table
  269.          mov bx,[bx]              ; BX now has the ascii value
  270.  
  271.          les di,OutBuf            ; Load ES:DI once
  272.          mov es:[di],bl           ; Store the character to the output buffer
  273.          inc di                   ; Now just inc DI
  274.          inc WORD PTR NumConvert  ; We converted the 1st character
  275.  
  276.          div cx                   ; DX will get the remainder
  277.          shl dx,1                 ; *2 for word addressing into ToAscii Table
  278.          mov bx,dx
  279.          xor dx,dx                ; Zero out DX for the next division
  280.          lea bx,ToAscii[bx]       ; BX points into the table
  281.          mov bx,[bx]              ; BX now has the ascii value
  282.  
  283.          mov es:[di],bl           ; Store the character to the output buffer
  284.          inc di
  285.          inc WORD PTR NumConvert  ; We converted the 2nd character
  286.  
  287.          div cx                   ; DX will get the remainder
  288.          shl dx,1                 ; *2 for word addressing into ToAscii Table
  289.          mov bx,dx
  290.          xor dx,dx                ; Zero out DX for the next division
  291.          lea bx,ToAscii[bx]       ; BX points into the table
  292.          mov bx,[bx]              ; BX now has the ascii value
  293.  
  294.          mov es:[di],bl           ; Store the character to the output buffer
  295.          inc di
  296.          mov word ptr [OutBuf],di ; Update the pointer offset
  297.          inc WORD PTR NumConvert  ; We converted the 3rd character
  298.  
  299.          dec WORD PTR NumWord     ; 1 less word to consider
  300.       jnz up10
  301.  
  302.       xor al,al
  303.       mov es:[di],al              ; Null terminate the buffer
  304.  
  305.       mov ax,NumConvert
  306.  ELSE
  307.       mov si,InpBuf               ; SI will point to the input buffer
  308.       mov di,OutBuf               ; DI will point to the output buffer
  309.  
  310.       cld
  311.  
  312. up10:    lodsw                    ; AX <-- [SI++]
  313. ;
  314. ; The following 3 blocks of code are identical. You could very easily
  315. ; loop over the first block 3 times and achieve the same effect. I however
  316. ; feel that speed is more important than memory utilization. As a result,
  317. ; I prefer to 'unwrap' the loop 3 times and produce the inline code, than
  318. ; suffer the penalties associated with flushing the prefetch queue when
  319. ; the necessary jump at the bottom of the loop is executed.
  320. ;
  321.          div cx                   ; DX will get the remainder
  322.          shl dx,1                 ; *2 for word addressing into ToAscii Table
  323.          mov bx,dx
  324.          xor dx,dx                ; Zero out DX for the next division
  325.          lea bx,ToAscii[bx]       ; BX points into the table
  326.          mov bx,[bx]              ; BX now has the ascii value
  327.          mov [di],bl              ; Store the character to the output buffer
  328.          inc di
  329.          inc WORD PTR NumConvert  ; We converted the 1st character
  330.  
  331.          div cx                   ; DX will get the remainder
  332.          shl dx,1                 ; *2 for word addressing into ToAscii Table
  333.          mov bx,dx
  334.          xor dx,dx                ; Zero out DX for the next division
  335.          lea bx,ToAscii[bx]       ; BX points into the table
  336.          mov bx,[bx]              ; BX now has the ascii value
  337.          mov [di],bl              ; Store the character to the output buffer
  338.          inc di
  339.          inc WORD PTR NumConvert  ; We converted the 2nd character
  340.  
  341.          div cx                   ; DX will get the remainder
  342.          shl dx,1                 ; *2 for word addressing into ToAscii Table
  343.          mov bx,dx
  344.          xor dx,dx                ; Zero out DX for the next division
  345.          lea bx,ToAscii[bx]       ; BX points into the table
  346.          mov bx,[bx]              ; BX now has the ascii value
  347.          mov [di],bl              ; Store the character to the output buffer
  348.          inc di
  349.          inc WORD PTR NumConvert  ; We converted the 3rd character
  350.  
  351.          dec WORD PTR NumWord     ; 1 less word to consider
  352.       jnz up10
  353.  
  354.       xor al,al
  355.       mov [di],al                 ; Null terminate the buffer
  356.  
  357.       mov ax,NumConvert
  358.  ENDIF
  359.  
  360. IFNDEF TASM                       ; Cleanup for MASM
  361.       ret
  362. UnPack3 endp
  363.  
  364. ELSE                              ; Clean up for TASM
  365.       pop di
  366.       pop si
  367.       mov sp,bp                   ; Deallocate the local variables
  368.       pop bp                      ; Reset BP
  369. _UnPack3 endp
  370. ENDIF
  371.  
  372.         end